package org.dromara.common.heweather.api;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.dromara.common.heweather.constant.CacheConstants;
import org.dromara.common.heweather.constant.HeWeatherConstant;
import org.dromara.common.heweather.dto.*;
import org.dromara.common.heweather.jwt.JwtHefengApi;
import org.dromara.common.heweather.properties.HeWeatherProperties;
import org.dromara.common.model.OkHttpUtils;
import org.dromara.common.redis.utils.RedisUtils;

import java.io.IOException;
import java.rmi.RemoteException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 天气预报
 * @Author: Stars
 * @Date: 2025/4/4 19:40
 */
@Slf4j
@RequiredArgsConstructor
public class HeWeatherForecast implements HeWeatherApi{

    private final HeWeatherProperties heWeatherProperties;

    @Override
    public List<CitySearchDTO> searchCity(String location) throws IOException {
        if (StringUtils.isBlank(location)) {
            throw new RemoteException("location不能为空");
        }
        String cacheKey = CacheConstants.CACHE_CITY_SEARCH_KEY + SecureUtil.md5(location);
        List<CitySearchDTO> cacheObject = RedisUtils.getCacheObject(cacheKey);
        if (cacheObject != null) {
            return cacheObject;
        }

        String jwt = JwtHefengApi.getJwt();
        Response response = OkHttpUtils.get(heWeatherProperties.getUrl() + HeWeatherConstant.CITY_SEARCH_URL, Map.of("location", location), Map.of("Authorization", "Bearer " + jwt));
        if (response.code() != 200) {
            log.error("请求和风天气 城市搜索失败 失败, code: {}, message: {}", response.code(), response.message());
            throw new RemoteException(response.message());
        }
        String body = response.body().string();
        if (StringUtils.isEmpty(body)) {
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(body);
        JSONArray nowArray = jsonObject.getJSONArray("location");
        List<CitySearchDTO> dailyWeatherForecastList = new ArrayList<>();
        if (nowArray != null) {
            for (int i = 0; i < nowArray.size(); i++) {
                JSONObject nowObject = nowArray.getJSONObject(i);
                if (nowObject != null) {
                    CitySearchDTO weatherNowDTO = nowObject.toJavaObject(CitySearchDTO.class);
                    dailyWeatherForecastList.add(weatherNowDTO);
                }
            }
        }
        if (CollectionUtil.isNotEmpty(dailyWeatherForecastList)) {
            RedisUtils.setCacheObject(cacheKey, dailyWeatherForecastList, Duration.ofDays(5));
        }
        return dailyWeatherForecastList;
    }

    @Override
    public WeatherNowDTO weatherNow(String location) throws IOException {
        if (StringUtils.isBlank(location)) {
            throw new RemoteException("location不能为空");
        }
        String cacheKey = CacheConstants.CACHE_WEATHER_NOW_KEY + SecureUtil.md5(location);
        WeatherNowDTO cacheObject = RedisUtils.getCacheObject(cacheKey);
        if (cacheObject != null) {
            return cacheObject;
        }
        String jwt = JwtHefengApi.getJwt();
        Response response = OkHttpUtils.get(heWeatherProperties.getUrl() + HeWeatherConstant.WEATHER_NOW_URL, Map.of("location", location), Map.of("Authorization", "Bearer " + jwt));
        if (response.code() != 200) {
            log.error("请求和风天气失败, code: {}, message: {}", response.code(), response.message());
            throw new RemoteException(response.message());
        }
        String body = response.body().string();
        if (StringUtils.isEmpty(body)) {
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(body);
        JSONObject nowObject = jsonObject.getJSONObject("now");
        if (nowObject != null) {
            WeatherNowDTO weatherNowDTO = nowObject.to(WeatherNowDTO.class);
            RedisUtils.setCacheObject(cacheKey, weatherNowDTO, Duration.ofMinutes(5));
            return weatherNowDTO;
        }
        return null;
    }

    @Override
    public List<DailyWeatherForecastDTO> dailyWeather(String location) throws IOException {
        if (StringUtils.isBlank(location)) {
            throw new RemoteException("location不能为空");
        }
        String cacheKey = CacheConstants.CACHE_DAILY_WEATHER_FORECAST_KEY + SecureUtil.md5(location);
        List<DailyWeatherForecastDTO> cacheObject = RedisUtils.getCacheObject(cacheKey);
        if (CollectionUtil.isNotEmpty(cacheObject)) {
            return cacheObject;
        }

        String jwt = JwtHefengApi.getJwt();
        Response response = OkHttpUtils.get(heWeatherProperties.getUrl() + HeWeatherConstant.DAILY_WEATHER_FORECAST_URL, Map.of("location", location), Map.of("Authorization", "Bearer " + jwt));
        if (response.code() != 200) {
            log.error("请求和风天气每日天气预报失败, code: {}, message: {}", response.code(), response.message());
            throw new RemoteException(response.message());
        }
        String body = response.body().string();
        if (StringUtils.isEmpty(body)) {
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(body);
        JSONArray nowArray = jsonObject.getJSONArray("daily");
        List<DailyWeatherForecastDTO> dailyWeatherForecastList = new ArrayList<>();
        if (nowArray != null) {
            for (int i = 0; i < nowArray.size(); i++) {
                JSONObject nowObject = nowArray.getJSONObject(i);
                if (nowObject != null) {
                    DailyWeatherForecastDTO weatherNowDTO = nowObject.toJavaObject(DailyWeatherForecastDTO.class);
                    RedisUtils.setCacheObject(cacheKey, weatherNowDTO, Duration.ofMinutes(5));
                    dailyWeatherForecastList.add(weatherNowDTO);
                }
            }
        }
        if (CollectionUtil.isNotEmpty(dailyWeatherForecastList)) {
            RedisUtils.setCacheObject(cacheKey, dailyWeatherForecastList, Duration.ofMinutes(5));
        }
        return dailyWeatherForecastList;
    }

    @Override
    public List<HourlyWeatherForecastDTO> hourlyWeatherForecast(String location) throws IOException {
        if (StringUtils.isBlank(location)) {
            throw new RemoteException("location不能为空");
        }
        String cacheKey = CacheConstants.CACHE_HOURLY_WEATHER_FORECAST_KEY + SecureUtil.md5(location);
        List<HourlyWeatherForecastDTO> cacheObject = RedisUtils.getCacheObject(cacheKey);
        if (CollectionUtil.isNotEmpty(cacheObject)) {
            return cacheObject;
        }

        String jwt = JwtHefengApi.getJwt();
        Response response = OkHttpUtils.get(heWeatherProperties.getUrl() + HeWeatherConstant.HOURLY_WEATHER_FORECAST_URL, Map.of("location", location), Map.of("Authorization", "Bearer " + jwt));
        if (response.code() != 200) {
            log.error("请求和风天气逐个小时天气预报失败, code: {}, message: {}", response.code(), response.message());
            throw new RemoteException(response.message());
        }
        String body = response.body().string();
        if (StringUtils.isEmpty(body)) {
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(body);
        JSONArray nowArray = jsonObject.getJSONArray("hourly");
        List<HourlyWeatherForecastDTO> hourlyWeatherForecastList = new ArrayList<>();
        if (nowArray != null) {
            for (int i = 0; i < nowArray.size(); i++) {
                JSONObject nowObject = nowArray.getJSONObject(i);
                if (nowObject != null) {
                    HourlyWeatherForecastDTO hourlyWeatherForecast = nowObject.toJavaObject(HourlyWeatherForecastDTO.class);
                    hourlyWeatherForecastList.add(hourlyWeatherForecast);
                }
            }
        }
        if (CollectionUtil.isNotEmpty(hourlyWeatherForecastList)) {
            RedisUtils.setCacheObject(cacheKey, hourlyWeatherForecastList, Duration.ofMinutes(5));
        }
        return hourlyWeatherForecastList;
    }

    @Override
    public List<WeatherIndexDTO> weatherIndex(String location, String type) throws IOException {
        if (StringUtils.isBlank(location)) {
            throw new RemoteException("location不能为空");
        }
        String cacheKey = CacheConstants.CACHE_WEATHER_INDEX_KEY + SecureUtil.md5(location);
        List<WeatherIndexDTO> cacheObject = RedisUtils.getCacheObject(cacheKey);
        if (CollectionUtil.isNotEmpty(cacheObject)) {
            return cacheObject;
        }

        String jwt = JwtHefengApi.getJwt();
        Response response = OkHttpUtils.get(heWeatherProperties.getUrl() + HeWeatherConstant.WEATHER_INDEX_URL, Map.of("location", location,"type",type), Map.of("Authorization", "Bearer " + jwt));
        if (response.code() != 200) {
            log.error("请求和风天气天气指数预报失败, code: {}, message: {}", response.code(), response.message());
            throw new RemoteException(response.message());
        }
        String body = response.body().string();
        if (StringUtils.isEmpty(body)) {
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(body);
        JSONArray nowArray = jsonObject.getJSONArray("daily");
        List<WeatherIndexDTO> weatherIndexList = new ArrayList<>();
        if (nowArray != null) {
            for (int i = 0; i < nowArray.size(); i++) {
                JSONObject nowObject = nowArray.getJSONObject(i);
                if (nowObject != null) {
                    WeatherIndexDTO weatherIndex = nowObject.toJavaObject(WeatherIndexDTO.class);
                    weatherIndexList.add(weatherIndex);
                }
            }
        }
        if (CollectionUtil.isNotEmpty(weatherIndexList)) {
            RedisUtils.setCacheObject(cacheKey, weatherIndexList, Duration.ofMinutes(5));
        }
        return weatherIndexList;
    }
}
